#ifndef __MEMORY_H__
#define __MEMORY_H__

// 8 Bytes per cell
#define PTRS_PER_PAGE     512

#define PAGE_OFFSET ((unsigned long)0xffff800000000000)

#define PAGE_GDT_SHIFT    39
#define PAGE_1G_SHIFT     30
#define PAGE_2M_SHIFT     21
#define PAGE_4K_SHIFT     12

#define PAGE_2M_SIZE      (1UL << PAGE_2M_SHIFT)
#define PAGE_4K_SIZE      (1UL << PAGE_4K_SHIFT)

#define PAGE_2M_MASK      (~ (PAGE_2M_SIZE -1))
#define PAGE_4K_MASK      (~ (PAGE_4K_SIZE -1))

#define PAGE_2M_ALIGN(addr)    (((unsigned long)(addr) + PAGE_2M_SIZE -1) &PAGE_2M_MASK)
#define PAGE_4K_ALIGN(addr)    (((unsigned long)(addr) + PAGE_4K_SIZE -1) &PAGE_4K_MASK)

#define Virt_To_Phy(addr)   ((unsigned long)(addr) - PAGE_OFFSET)
#define Phy_To_Virt(addr)  ((unsigned long *)((unsigned long)(addr) + PAGE_OFFSET))

struct E820
{
    unsigned long address;
    unsigned long length;
    unsigned int     type;
}__attribute__((packed));

struct Global_Memory_Descriptor
{
    struct E820      e820[32];
    unsigned long    e820_length;
};

extern struct Global_Memory_Descriptor memory_management_struct;

#include "printk.h"
#include "lib.h"
void init_memory();
struct Memory_E820_Formate
{
    unsigned int address1;
    unsigned int address2;
    unsigned int length1;
    unsigned int length2;
    unsigned int type;
};

#endif